package com.jin.jpa.wrapper;

import com.jin.jpa.wrapper.expression.GroupByExpression;
import com.jin.jpa.wrapper.expression.IExpression;
import com.jin.jpa.wrapper.expression.OrderByExpression;
import com.jin.jpa.wrapper.expression.SelectExpression;
import com.jin.jpa.wrapper.support.FieldFunction;
import com.jin.jpa.wrapper.support.IWrapper;
import com.jin.jpa.wrapper.util.LambdaUtils;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: yuanxiuyao
 * @Date: 2024/1/8 16:31
 * @PackageName: org.example.jpa.wrapper.expression
 * @Version 1.0
 */
public interface AbstractOtherWrapper<T> extends IWrapper<T> {

    List<IExpression<?>> expressionList = new ArrayList<>();

    @Override
    default IWrapper<T> orderByAsc(FieldFunction<T, ?> expression){
        PropertyDescriptor propertyDescriptor = LambdaUtils.extract(expression, getInstanceClass());
        expressionList.add(OrderByExpression.asc(propertyDescriptor.getName()));
        return this;
    }

    @Override
    default IWrapper<T> orderByDesc(FieldFunction<T, ?> expression){
        PropertyDescriptor propertyDescriptor = LambdaUtils.extract(expression, getInstanceClass());
        expressionList.add(OrderByExpression.desc(propertyDescriptor.getName()));
        return this;
    }

    @Override
    default IWrapper<T> groupBy(FieldFunction<T, ?> expression){
        PropertyDescriptor propertyDescriptor = LambdaUtils.extract(expression, getInstanceClass());
        expressionList.add(GroupByExpression.of(propertyDescriptor.getName()));
        return this;
    }

    default <T> List<T> filterExpression(Class<T> clazz){
        return (List<T>) expressionList.stream().filter(o -> org.springframework.util.ClassUtils.isAssignable(clazz, o.getClass()))
                .collect(Collectors.toList());
    }
}
